package no.saiboten.milkywave.controller;

import java.text.MessageFormat;
import java.util.List;
import java.util.logging.Logger;

import no.saiboten.milkywave.component.WaterLevelEntity;
import no.saiboten.milkywave.entity.Event;
import no.saiboten.milkywave.entity.MailContent;
import no.saiboten.milkywave.entity.User;
import no.saiboten.milkywave.graph.GraphService;
import no.saiboten.milkywave.mail.MailSender;
import no.saiboten.milkywave.service.EventService;
import no.saiboten.milkywave.service.MilkyWaveHttpService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import com.googlecode.objectify.Objectify;
import com.googlecode.objectify.ObjectifyService;
import com.googlecode.objectify.Query;

@Controller
public class CronjobController {

	private static final Logger LOGGER = Logger
			.getLogger(CronjobController.class.getName());

	private MilkyWaveHttpService milkyService;

	WaterLevelEntity waterLevel;

	Objectify ofy;

	private MailSender mailSender;

	private EventService eventService;

	private boolean hasSentMailToday = false;

	GraphService graphService;

	@Autowired
	public CronjobController(MailSender mail,
			MilkyWaveHttpService milkyService, WaterLevelEntity waterLevel,
			EventService eventService, GraphService graphService) {
		this.mailSender = mail;
		this.milkyService = milkyService;
		this.waterLevel = waterLevel;
		this.eventService = eventService;
		this.graphService = graphService;

		ofy = ObjectifyService.begin();
	}

	@RequestMapping("/cron/checkmilkywave")
	public ModelAndView checkMilkyWayAndNotify() {
		ModelAndView mav = new ModelAndView("milkycheck");

		Double value = milkyService.findLatestValue();
		waterLevel.setCurrentWaterLevel(value);

		graphService.registerNewPlot(value);

		mav.addObject("result", "Vannføring: " + value);

		if (value > waterLevel.getWaterLevel() && !hasSentMailToday) {
			LOGGER.info("Great results! It's value is: " + value
					+ ". Sending mail!");

			Long id = eventService.createEvent();
			Event event = eventService.getEvent(id);

			sendMails(id, event.getKeyToUserMap(), value);
			hasSentMailToday = true;
		} else {
			LOGGER.info("Not enought water to send out notification. Value: "
					+ value);
		}

		return mav;
	}

	@RequestMapping("/cron/resetmail")
	public ModelAndView resetMailNotification() {
		ModelAndView mav = new ModelAndView("milkycheck");
		hasSentMailToday = false;

		mav.addObject("result", "Mail has been reset!");
		return mav;
	}

	private void sendMails(Long id, List<String> map, Double value) {
		Query<User> mails = ofy.query(User.class);
		for (User reciever : mails) {
			if (reciever.isConfirmed()) {

				String key = null;

				for (String mapKey : map) {
					String[] mapInPieces = mapKey.split("=");
					if (mapInPieces[1].equals(reciever.getMail())) {
						key = mapInPieces[0];
					}
				}

				boolean result = mailSender.sendMail(reciever.getMail(),
						"It's milky wave time!!", MessageFormat.format(
								getMailContent(), value, id, key,
								reciever.getDeletionCode()));

				LOGGER.info("Sending mail to " + reciever.getMail()
						+ " with result: " + result);
			} else {
				LOGGER.info("User " + reciever + " has not confirmed mail");
			}
		}
	}

	public String getMailContent() {
		MailContent mailContent = ofy.get(MailContent.class, 1);
		if (mailContent != null) {
			return mailContent.getContent();
		}

		LOGGER.info("Could not retrieve mailcontent from db. It' value is null?");
		return "Kom dere ut i elven, nå er vannføringen på hele {0}! Din nøkkel er: http://themilkywave.appspot.com/event/join/{1}/{2})";
	}
}
